/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */
using System;
using Parser = Velocity4Net.Runtime.Parse.Parser;
using InternalContextAdapter = Velocity4Net.Ctx.InternalContextAdapter;
namespace Velocity4Net.Runtime.Parse.AST
{

    /// <summary> ASTStringLiteral support.  Will interpolate!
    /// *
    /// </summary>
    /// <author> <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
    /// </author>
    /// <author> <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    /// </author>
    /// <version> $Id: ASTStringLiteral.cs,v 1.3 2003/10/27 13:54:10 corts Exp $
    ///
    /// </version>
    public class ASTStringLiteral : SimpleNode
    {
        /* cache the value of the interpolation switch */
        private bool interpolate = true;
        private SimpleNode nodeTree = null;
        private System.String image = "";
        private System.String interpolateimage = "";

        public ASTStringLiteral(int id) : base(id) { }

        public ASTStringLiteral(Parser p, int id) : base(p, id) { }

        /// <summary>  init : we don't have to do much.  Init the tree (there
        /// shouldn't be one) and then see if interpolation is turned on.
        /// </summary>
        public override System.Object Init(InternalContextAdapter context, System.Object data)
        {
            /*
            *  simple habit...  we prollie don't have an AST beneath us
            */

            base.Init(context, data);

            /*
            *  the stringlit is set at template parse time, so we can 
            *  do this here for now.  if things change and we can somehow 
            * create stringlits at runtime, this must
            *  move to the runtime execution path
            *
            *  so, only if interpolation is turned on AND it starts 
            *  with a " AND it has a  directive or reference, then we 
            *  can  interpolate.  Otherwise, don't bother.
            */

            interpolate = rsvc.GetBoolean(Velocity4Net.Runtime.RuntimeConstants.INTERPOLATE_STRINGLITERALS, true) && FirstToken.image.StartsWith("\"") && ((FirstToken.image.IndexOf((System.Char)'$') != -1) || (FirstToken.image.IndexOf((System.Char)'#') != -1));

            /*
            *  get the contents of the string, minus the '/" at each end
            */

            image = FirstToken.image.Substring(1, (FirstToken.image.Length - 1) - (1));

            /*
            * tack a space on the end (dreaded <MORE> kludge)
            */

            interpolateimage = image + " ";

            if (interpolate)
            {
                /*
                *  now parse and init the nodeTree
                */
                //UPGRADE_ISSUE: The equivalent of constructor 'java.io.BufferedReader.BufferedReader' is incompatible with the expected type in C#. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1109"'
                System.IO.TextReader br = new System.IO.StringReader(interpolateimage);

                /*
                * it's possible to not have an initialization context - or we don't
                * want to trust the caller - so have a fallback value if so
                *
                *  Also, do *not* dump the VM namespace for this template
                */

                nodeTree = rsvc.Parse(br, (context != null) ? context.CurrentTemplateName : "StringLiteral", false);

                /*
                *  init with context. It won't modify anything
                */

                nodeTree.Init(context, rsvc);
            }

            return data;
        }

        /// <summary>  renders the value of the string literal
        /// If the properties allow, and the string literal contains a $ or a #
        /// the literal is rendered against the context
        /// Otherwise, the stringlit is returned.
        /// </summary>
        public override System.Object GetValue(InternalContextAdapter context)
        {
            if (interpolate)
            {
                try
                {
                    /*
                    *  now render against the real context
                    */

                    System.IO.TextWriter writer = new System.IO.StringWriter();
                    nodeTree.Render(context, writer);

                    /*
                    * and return the result as a String
                    */

                    System.String ret = writer.ToString();

                    /*
                    *  remove the space from the end (dreaded <MORE> kludge)
                    */

                    return ret.Substring(0, (ret.Length - 1) - (0));
                }
                catch (System.Exception e)
                {
                    /*
                    *  eh.  If anything wrong, just punt 
                    *  and output the literal 
                    */
                    rsvc.error("Error in interpolating string literal : " + e);
                }
            }

            /*
            *  ok, either not allowed to interpolate, there wasn't 
            *  a ref or directive, or we failed, so
            *  just output the literal
            */

            return image;
        }
    }
}
